#!/bin/bash

# =================================================
# 智能排产系统一键部署脚本
# 本地Git Bash执行脚本
# =================================================

# 配置变量
SERVER_HOST="117.72.45.141"
SERVER_USER="root"
SERVER_PORT="22"

APP_NAME="production-scheduling"
LOCAL_JAR="target/${APP_NAME}.jar"
REMOTE_APP_DIR="/app/${APP_NAME}"
DEPLOY_DIR="deploy"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_step() {
    echo -e "${BLUE}[STEP]${NC} $1"
}

# 检查必要环境
check_requirements() {
    log_step "1. 检查部署环境"

    # 检查Maven
    if ! command -v mvn &> /dev/null; then
        log_error "Maven未安装，请先安装Maven"
        exit 1
    fi
    log_info "Maven版本: $(mvn -version | head -1)"

    # 检查SSH连接 - 先尝试免密登录，失败则提示密码登录
    log_info "测试SSH连接到服务器..."
    if ssh -o BatchMode=yes -o ConnectTimeout=5 ${SERVER_USER}@${SERVER_HOST} exit &> /dev/null; then
        log_info "✅ SSH免密登录连接成功"
    else
        log_warn "❌ SSH免密登录失败，尝试密码登录..."
        # 尝试密码登录
        if ssh -o ConnectTimeout=10 ${SERVER_USER}@${SERVER_HOST} exit; then
            log_info "✅ SSH密码登录连接成功"
            log_warn "⚠️  建议配置SSH免密登录以获得更好的体验"
            log_info "💡 免密登录配置方法："
            log_info "   1. 生成密钥: ssh-keygen -t rsa -b 4096"
            log_info "   2. 复制公钥: ssh-copy-id ${SERVER_USER}@${SERVER_HOST}"
            log_info "   3. 测试登录: ssh ${SERVER_USER}@${SERVER_HOST}"
            log_info "   或运行: $0 --setup-ssh 来自动配置"
            echo ""
            read -p "是否继续部署？(y/N): " -n 1 -r
            echo ""
            if [[ ! $REPLY =~ ^[Yy]$ ]]; then
                log_info "部署已取消"
                exit 0
            fi
        else
            log_error "❌ SSH连接失败，请检查："
            log_error "   - 网络连接是否正常"
            log_error "   - 服务器地址是否正确: ${SERVER_HOST}"
            log_error "   - 用户名是否正确: ${SERVER_USER}"
            log_error "   - 服务器是否开启SSH服务"
            exit 1
        fi
    fi

    log_info "环境检查完成"
}

# 构建项目
build_project() {
    log_step "2. 构建项目"

    log_info "清理旧构建..."
    mvn clean

    log_info "开始Maven构建..."
    if mvn package -Dmaven.test.skip=true; then
        log_info "构建成功"
    else
        log_error "构建失败，请检查代码"
        exit 1
    fi

    # 检查JAR文件
    if [ ! -f "$LOCAL_JAR" ]; then
        log_error "JAR文件不存在: $LOCAL_JAR"
        exit 1
    fi

    JAR_SIZE=$(du -h "$LOCAL_JAR" | cut -f1)
    log_info "JAR文件大小: $JAR_SIZE"
}

# 准备部署文件
prepare_deploy_files() {
    log_step "3. 准备部署文件"

    # 创建部署目录
    mkdir -p $DEPLOY_DIR

    # 复制JAR文件
    cp $LOCAL_JAR $DEPLOY_DIR/${APP_NAME}.jar
    log_info "JAR文件已准备: $DEPLOY_DIR/${APP_NAME}.jar"

    # 检查startup.sh是否存在
    if [ ! -f "$DEPLOY_DIR/startup.sh" ]; then
        log_error "启动脚本不存在: $DEPLOY_DIR/startup.sh"
        exit 1
    fi
    
    # 在本地处理startup.sh换行符（如果可能的话）
    log_info "处理本地startup.sh换行符..."
    if command -v dos2unix &> /dev/null; then
        dos2unix $DEPLOY_DIR/startup.sh
        log_info "本地换行符转换完成"
    elif command -v sed &> /dev/null; then
        # 使用sed去除Windows换行符
        sed -i 's/\r$//' $DEPLOY_DIR/startup.sh
        log_info "使用sed处理换行符完成"
    else
        log_warn "本地无法处理换行符，将在服务器端处理"
    fi

    log_info "部署文件准备完成"
}

# 停止远程应用
stop_remote_app() {
    log_step "4. 停止远程应用"

    log_info "连接服务器停止应用..."
    ssh ${SERVER_USER}@${SERVER_HOST} "
        if [ -f ${REMOTE_APP_DIR}/startup.sh ]; then
            cd ${REMOTE_APP_DIR}
            chmod +x startup.sh
            ./startup.sh stop
        else
            echo '应用未部署或启动脚本不存在'
        fi
    "
}

# 上传文件到服务器
upload_files() {
    log_step "5. 上传部署文件"

    log_info "创建远程目录..."
    ssh ${SERVER_USER}@${SERVER_HOST} "mkdir -p ${REMOTE_APP_DIR}"

    log_info "上传JAR文件..."
    scp $DEPLOY_DIR/${APP_NAME}.jar ${SERVER_USER}@${SERVER_HOST}:${REMOTE_APP_DIR}/
    if [ $? -eq 0 ]; then
        log_info "JAR文件上传成功"
    else
        log_error "JAR文件上传失败"
        exit 1
    fi

    log_info "上传启动脚本..."
    scp $DEPLOY_DIR/startup.sh ${SERVER_USER}@${SERVER_HOST}:${REMOTE_APP_DIR}/
    if [ $? -eq 0 ]; then
        log_info "启动脚本上传成功"
    else
        log_error "启动脚本上传失败"
        exit 1
    fi

    log_info "处理启动脚本换行符和权限..."
    ssh ${SERVER_USER}@${SERVER_HOST} "
        cd ${REMOTE_APP_DIR}
        
        # 检查并安装dos2unix
        if ! command -v dos2unix &> /dev/null; then
            echo '安装dos2unix工具...'
            # 尝试yum安装（CentOS/RHEL）
            if command -v yum &> /dev/null; then
                yum install -y dos2unix
            # 尝试apt安装（Ubuntu/Debian）
            elif command -v apt-get &> /dev/null; then
                apt-get update && apt-get install -y dos2unix
            # 尝试dnf安装（Fedora）
            elif command -v dnf &> /dev/null; then
                dnf install -y dos2unix
            else
                echo '无法自动安装dos2unix，请手动安装'
                exit 1
            fi
        fi
        
        # 转换换行符
        echo '转换startup.sh换行符...'
        dos2unix startup.sh
        
        # 设置执行权限
        echo '设置startup.sh执行权限...'
        chmod +x startup.sh
        
        # 验证脚本可执行性
        echo '验证脚本...'
        if ./startup.sh --help >/dev/null 2>&1 || [[ \$? -eq 1 ]]; then
            echo 'startup.sh脚本验证成功'
        else
            echo 'startup.sh脚本验证失败'
            exit 1
        fi
    "
    
    if [ $? -eq 0 ]; then
        log_info "启动脚本处理完成"
    else
        log_error "启动脚本处理失败"
        exit 1
    fi
}

# 启动远程应用
start_remote_app() {
    log_step "6. 启动应用"

    log_info "在服务器上启动应用..."
    
    # 增强的远程启动逻辑
    ssh ${SERVER_USER}@${SERVER_HOST} "
        echo '=== 远程启动开始 ==='
        cd ${REMOTE_APP_DIR} || { echo 'CD失败'; exit 1; }
        echo '当前目录:' \$(pwd)
        echo '文件列表:'
        ls -la
        echo '检查startup.sh权限:'
        ls -la startup.sh
        echo '执行启动命令:'
        chmod +x startup.sh
        ./startup.sh start
        echo '启动命令执行完成'
        sleep 5
        echo '检查启动状态:'
        ./startup.sh status
        echo '=== 远程启动结束 ==='
    "
    
    if [ $? -eq 0 ]; then
        log_info "远程启动命令执行成功"
    else
        log_error "远程启动命令执行失败"
        log_warn "可能是startup.sh换行符问题，尝试运行: $0 --fix"
        exit 1
    fi
}

# 验证部署
verify_deployment() {
    log_step "7. 验证部署"

    log_info "等待应用完全启动..."
    sleep 20

    log_info "检查应用状态..."
    ssh ${SERVER_USER}@${SERVER_HOST} "
        cd ${REMOTE_APP_DIR}
        echo '=== 验证部署状态 ==='
        ./startup.sh status
        echo '=== 检查端口监听 ==='
        netstat -tlnp | grep 8091 || echo '8091端口未监听'
        echo '=== 检查进程 ==='
        ps aux | grep production-scheduling | grep -v grep || echo '未找到应用进程'
        echo '=== 验证结束 ==='
    "

    log_info "测试健康检查接口..."
    # 多次尝试健康检查
    for i in {1..5}; do
        if curl -s --connect-timeout 10 "http://${SERVER_HOST}:8091/actuator/health" > /dev/null; then
            log_info "✅ 健康检查通过 (尝试 $i/5)"
            break
        else
            log_warn "⚠️  健康检查失败，重试中... ($i/5)"
            sleep 10
        fi
    done

    echo ""
    log_info "🎉 部署完成！"
    log_info "🌐 应用访问地址: http://${SERVER_HOST}:8091"
    log_info "📚 API文档地址: http://${SERVER_HOST}:8091/swagger-ui.html"
    log_info "💚 健康检查: http://${SERVER_HOST}:8091/actuator/health"
    log_info "📊 监控端点: http://${SERVER_HOST}:8092"
    echo ""
    log_info "如需查看日志，请执行:"
    log_info "ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${REMOTE_APP_DIR} && ./startup.sh logs'"
}

# 清理本地文件
cleanup() {
    log_step "8. 清理本地文件"

    if [ "$1" != "--keep-deploy" ]; then
        log_info "清理部署文件..."
        rm -f $DEPLOY_DIR/${APP_NAME}.jar
        log_info "本地部署文件已清理"
    else
        log_info "保留部署文件"
    fi
}

# 显示帮助信息
show_help() {
    echo "智能排产系统部署脚本"
    echo ""
    echo "使用方法:"
    echo "  $0 [选项]"
    echo ""
    echo "选项:"
    echo "  --help              显示帮助信息"
    echo "  --keep-deploy       保留本地部署文件"
    echo "  --skip-build        跳过构建步骤(使用已有JAR)"
    echo "  --only-upload       仅上传文件，不重启应用"
    echo "  --troubleshoot      故障排查模式，收集服务器信息"
    echo "  --fix               修复startup.sh换行符问题"
    echo "  --setup-ssh         配置SSH免密登录"
    echo ""
    echo "示例:"
    echo "  $0                  完整部署"
    echo "  $0 --keep-deploy    部署后保留文件"
    echo "  $0 --skip-build     跳过构建直接部署"
    echo "  $0 --troubleshoot   排查部署问题"
    echo "  $0 --fix            修复startup.sh换行符问题"
    echo "  $0 --setup-ssh      首次配置SSH免密登录"
}

# SSH免密登录配置
setup_ssh() {
    log_step "配置SSH免密登录"

    # 检查本地SSH密钥
    if [ ! -f ~/.ssh/id_rsa.pub ]; then
        log_info "生成SSH密钥对..."
        ssh-keygen -t rsa -b 4096 -C "deployment-key-$(date +%Y%m%d)" -f ~/.ssh/id_rsa -N ""
        if [ $? -eq 0 ]; then
            log_info "✅ SSH密钥生成成功"
        else
            log_error "❌ SSH密钥生成失败"
            exit 1
        fi
    else
        log_info "✅ 发现现有SSH密钥"
    fi

    # 显示公钥
    log_info "📋 您的SSH公钥："
    echo ""
    cat ~/.ssh/id_rsa.pub
    echo ""

    # 复制公钥到服务器
    log_info "复制公钥到服务器..."
    if command -v ssh-copy-id &> /dev/null; then
        if ssh-copy-id -i ~/.ssh/id_rsa.pub ${SERVER_USER}@${SERVER_HOST}; then
            log_info "✅ 公钥复制成功"
        else
            log_error "❌ 公钥复制失败"
            log_info "💡 您可以手动复制上面的公钥到服务器："
            log_info "   1. 登录服务器: ssh ${SERVER_USER}@${SERVER_HOST}"
            log_info "   2. 创建目录: mkdir -p ~/.ssh && chmod 700 ~/.ssh"
            log_info "   3. 添加公钥: echo '你的公钥' >> ~/.ssh/authorized_keys"
            log_info "   4. 设置权限: chmod 600 ~/.ssh/authorized_keys"
            exit 1
        fi
    else
        log_warn "⚠️  ssh-copy-id不可用，请手动配置"
        log_info "💡 手动配置步骤："
        log_info "   1. 复制上面显示的公钥"
        log_info "   2. 登录服务器: ssh ${SERVER_USER}@${SERVER_HOST}"
        log_info "   3. 执行以下命令:"
        log_info "      mkdir -p ~/.ssh && chmod 700 ~/.ssh"
        log_info "      echo '粘贴公钥内容' >> ~/.ssh/authorized_keys"
        log_info "      chmod 600 ~/.ssh/authorized_keys"
        exit 0
    fi

    # 测试免密登录
    log_info "测试免密登录..."
    if ssh -o BatchMode=yes -o ConnectTimeout=5 ${SERVER_USER}@${SERVER_HOST} exit &> /dev/null; then
        log_info "🎉 SSH免密登录配置成功！"
        log_info "现在您可以无密码执行部署脚本了"
    else
        log_error "❌ 免密登录测试失败"
        log_info "请检查服务器SSH配置："
        log_info "   sudo vim /etc/ssh/sshd_config"
        log_info "   确保以下配置启用："
        log_info "   PubkeyAuthentication yes"
        log_info "   AuthorizedKeysFile .ssh/authorized_keys"
        log_info "   然后重启SSH服务: sudo systemctl restart sshd"
        exit 1
    fi
}

# 故障排查
troubleshoot() {
    log_step "故障排查模式"

    log_info "收集服务器信息..."
    ssh ${SERVER_USER}@${SERVER_HOST} "
        echo '=== 系统信息 ==='
        date
        uptime
        df -h
        free -m
        
        echo '=== 应用目录信息 ==='
        cd ${REMOTE_APP_DIR}
        pwd
        ls -la
        
        echo '=== startup.sh脚本检查 ==='
        if [ -f startup.sh ]; then
            echo '文件权限:' \$(ls -la startup.sh)
            echo '文件类型:' \$(file startup.sh)
            echo '换行符检查:'
            if command -v dos2unix &> /dev/null; then
                dos2unix -i startup.sh
            else
                echo 'dos2unix未安装，无法检查换行符'
            fi
            echo '脚本头部:'
            head -3 startup.sh | cat -A
        else
            echo 'startup.sh文件不存在'
        fi
        
        echo '=== Java环境 ==='
        java -version
        
        echo '=== 端口监听 ==='
        netstat -tlnp | grep -E '(8091|13306|6379)'
        
        echo '=== 应用进程 ==='
        ps aux | grep production-scheduling | grep -v grep
        
        echo '=== 应用日志（最后20行）==='
        tail -20 ${REMOTE_APP_DIR}/logs/startup.log 2>/dev/null || echo '启动日志不存在'
        tail -20 ${REMOTE_APP_DIR}/logs/production-scheduling.log 2>/dev/null || echo '应用日志不存在'
        
        echo '=== Docker容器状态 ==='
        docker ps -a
    "
}

# 修复startup.sh换行符问题
fix_startup() {
    log_step "修复startup.sh换行符问题"

    log_info "连接服务器修复startup.sh..."
    ssh ${SERVER_USER}@${SERVER_HOST} "
        cd ${REMOTE_APP_DIR}
        
        echo '=== 修复开始 ==='
        
        # 检查并安装dos2unix
        if ! command -v dos2unix &> /dev/null; then
            echo '安装dos2unix工具...'
            if command -v yum &> /dev/null; then
                yum install -y dos2unix
            elif command -v apt-get &> /dev/null; then
                apt-get update && apt-get install -y dos2unix
            elif command -v dnf &> /dev/null; then
                dnf install -y dos2unix
            else
                echo '尝试使用sed修复...'
                sed -i 's/\r\$//' startup.sh
                chmod +x startup.sh
                echo 'sed修复完成'
                exit 0
            fi
        fi
        
        # 转换换行符
        echo '转换startup.sh换行符...'
        dos2unix startup.sh
        
        # 设置权限
        chmod +x startup.sh
        
        # 测试脚本
        echo '测试startup.sh脚本...'
        if ./startup.sh status >/dev/null 2>&1 || [[ \$? -eq 0 ]]; then
            echo '✅ startup.sh修复成功！'
        else
            echo '❌ startup.sh仍有问题'
            exit 1
        fi
        
        echo '=== 修复完成 ==='
    "
    
    if [ $? -eq 0 ]; then
        log_info "startup.sh修复成功！现在可以正常使用了"
    else
        log_error "修复失败，请手动检查"
    fi
}

# 主函数
main() {
    local SKIP_BUILD=false
    local ONLY_UPLOAD=false
    local KEEP_DEPLOY=false

    # 解析参数
    for arg in "$@"; do
        case $arg in
            --help)
                show_help
                exit 0
                ;;
            --skip-build)
                SKIP_BUILD=true
                ;;
            --only-upload)
                ONLY_UPLOAD=true
                ;;
            --keep-deploy)
                KEEP_DEPLOY=true
                ;;
            --troubleshoot)
                troubleshoot
                exit 0
                ;;
            --fix)
                fix_startup
                exit 0
                ;;
            --setup-ssh)
                setup_ssh
                exit 0
                ;;
            *)
                log_error "未知参数: $arg"
                show_help
                exit 1
                ;;
        esac
    done

    echo "🚀 智能排产系统部署开始"
    echo "=================================================="

    # 执行部署流程
    check_requirements

    if [ "$SKIP_BUILD" = false ]; then
        build_project
    else
        log_info "跳过构建步骤"
        if [ ! -f "$LOCAL_JAR" ]; then
            log_error "JAR文件不存在: $LOCAL_JAR，请先构建项目"
            exit 1
        fi
    fi

    prepare_deploy_files

    if [ "$ONLY_UPLOAD" = false ]; then
        stop_remote_app
    fi

    upload_files

    if [ "$ONLY_UPLOAD" = false ]; then
        start_remote_app
        verify_deployment
    else
        log_info "仅上传模式，跳过应用重启"
    fi

    if [ "$KEEP_DEPLOY" = true ]; then
        cleanup --keep-deploy
    else
        cleanup
    fi

    echo "=================================================="
    echo "🎉 部署脚本执行完成！"
}

# 执行主函数
main "$@"